package com.tensquare.article.service;

import com.tensquare.article.dao.ArticleDao;
import com.tensquare.article.pojo.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.IdWorker;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Alfred
 * @description redis存入对象数据  该对象必须实现序列化
 * @date 2021/4/23 20:33
 */
@Service
public class ArticleService {

    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * fetch data by rule id
     *
     * @description  增加文章
     * @param
     * @return
     */
    public void add(Article article){
        article.setId(idWorker.nextId()+"");
        articleDao.save(article);
    }

    /**
     * fetch data by rule id
     *
     * @description  文章全部列表
     * @param
     * @return
     */
    public List<Article> findAll(){
        return articleDao.findAll();
    }

    /**
     * fetch data by rule id
     *
     * @description  根据ID查询文章
     * @param
     * @return
     */
    public Article findById(String id){
        //从缓存中提取
        Article article = (Article) redisTemplate.opsForValue().get("article_"+id);
        //如果缓存中没有则查询数据库并放入缓存   设置缓存过期时间
        if (article==null){
            article = articleDao.findById(id).get();
            redisTemplate.opsForValue().set("article_"+id,article,1, TimeUnit.HOURS);
        }

        return article;
    }

    /**
     * fetch data by rule id
     *
     * @description  修改文章
     * @param
     * @return
     */
    public void update(Article article){
        redisTemplate.delete("article_"+article.getId());//删除该条记录缓存
        articleDao.save(article);
    }

    /**
     * fetch data by rule id
     *
     * @description  根据ID删除文章
     * @param
     * @return
     */
    public void deleteById(String id){
        redisTemplate.delete("article_"+id);//删除该条记录缓存
        articleDao.deleteById(id);
    }

    /**
     * fetch data by rule id
     *
     * @description  构建查询条件
     * @param
     * @return
     */
    public Specification<Article> createSpecification(Map searchMap){
        return new Specification<Article>(){

            @Override
            public Predicate toPredicate(Root<Article> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<>();
                if(searchMap.get("columnid")!=null && !"".equals(searchMap.get("columnid"))){
                    predicateList.add(cb.like(root.get("columnid").as(String.class),"%"+(String) searchMap.get("columnid")+"%"));
                }
                if(searchMap.get("title")!=null && !"".equals(searchMap.get("title"))){
                    predicateList.add(cb.equal(root.get("title").as(String.class),(String) searchMap.get("title")));
                }
                if(searchMap.get("ispublic")!=null && !"".equals(searchMap.get("ispublic"))){
                    predicateList.add(cb.equal(root.get("ispublic").as(String.class),(String) searchMap.get("ispublic")));
                }
                if(searchMap.get("image")!=null && !"".equals(searchMap.get("image"))){
                    predicateList.add(cb.equal(root.get("image").as(String.class),(String) searchMap.get("image")));
                }
                if(searchMap.get("istop")!=null && !"".equals(searchMap.get("istop"))){
                    predicateList.add(cb.equal(root.get("istop").as(String.class),(String) searchMap.get("istop")));
                }
                if(searchMap.get("visits")!=null && !"".equals(searchMap.get("visits"))){
                    predicateList.add(cb.equal(root.get("visits").as(String.class),(String) searchMap.get("visits")));
                }
                if(searchMap.get("channelid")!=null && !"".equals(searchMap.get("channelid"))){
                    predicateList.add(cb.equal(root.get("channelid").as(String.class),(String) searchMap.get("channelid")));
                }
                if(searchMap.get("state")!=null && !"".equals(searchMap.get("state"))){
                    predicateList.add(cb.equal(root.get("state").as(String.class),(String) searchMap.get("state")));
                }
                if(searchMap.get("type")!=null && !"".equals(searchMap.get("type"))){
                    predicateList.add(cb.equal(root.get("type").as(String.class),(String) searchMap.get("type")));
                }
                if(searchMap.get("url")!=null && !"".equals(searchMap.get("url"))){
                    predicateList.add(cb.equal(root.get("url").as(String.class),(String) searchMap.get("url")));
                }

                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
    }

    /**
     * fetch data by rule id
     *
     * @description  根据条件查询文章列表
     * @param
     * @return
     */
    public List<Article> findSearch(Map searchMap){
        Specification<Article> specification = createSpecification(searchMap);
        return articleDao.findAll(specification);
    }

    /**
     * fetch data by rule id
     *
     * @description  文章分页 + 条件查询
     * @param
     * @return
     */
    public Page<Article> findSearch(Map searchMap,int page,int size){
        Specification<Article> specification = createSpecification(searchMap);
        PageRequest pageRequest = PageRequest.of(page-1,size);
        return articleDao.findAll(specification,pageRequest);
    }

    /**
     * fetch data by rule id
     *
     * @description  点赞
     * @param
     * @return
     */
    @Transactional
    public int updateThumbup(String id){
        return articleDao.updateThumbup(id);
    }

    /**
     * fetch data by rule id
     *
     * @description  文章审核
     * @param
     * @return
     */
    @Transactional
    public void examine(String id){
        articleDao.examine(id);
    }

    /**
     * fetch data by rule id
     *
     * @description  根据频道ID获取文章列表
     * @param
     * @return
     */
    public Page<Article> findArticlesByChannelid(String channelid,int page,int size){
        PageRequest pageRequest = PageRequest.of(page-1, size);
        return articleDao.findByChannelid(channelid,pageRequest);
    }

    /**
     * fetch data by rule id
     *
     * @description  根据专栏ID获取文章列表
     * @param
     * @return
     */
    public Page<Article> findArticlesByColumnid(String columnid,int page,int size){
        PageRequest pageRequest = PageRequest.of(page-1, size);
        return articleDao.findByColumnid(columnid,pageRequest);
    }

    /**
     * fetch data by rule id
     *
     * @description  头条文章
     * @param
     * @return
     */
    @Transactional
    public List<Article> findArticlesByIstop(){
        return articleDao.findArticlesByIstop("1");
    }
}
